﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
namespace SSCCMembership.Web.Services.Members
{
    [ErrorHandlerBehavior]
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PrintingService
    {
        [OperationContract]
        public HowManyPages LoadNumberOfPages()
        {
            string UserName = HttpContext.Current.User.Identity.Name;
            bool[] RequiresConsent = new bool[0];
            using (var Q = SSCCDatabase.Query("SELECT Ms.ParentalConsentReqd FROM SSCC_DAT_Family AS F INNER JOIN SSCC_DAT_Membership AS Ms ON F.Member = Ms.Member INNER JOIN SSCC_DAT_Year AS Y ON Ms.Year = Y.ID WHERE (F.UserID = @Username) AND (Y.StartDate < @NOW) AND (Y.EndDate > @NOW) AND (Ms.RenewChecked = 1)", new Params()
            {
                {new SqlParameter("@Username", SqlDbType.VarChar), UserName},
                {new SqlParameter("@NOW", SqlDbType.Date), DateTime.Now}
            }))
            {
                RequiresConsent = Q.Select((R) => R["ParentalConsentReqd"].Nullable<bool?>() == true).ToArray();
            }
            int LegalStatements = RequiresConsent.Length - 2;
            int Pages = 0;
            while (LegalStatements > 0)
            {
                Pages++;
                LegalStatements -= NumberPerPage;
            }
            return new HowManyPages() { NumberOfAdditionalPages = Pages, NumberOfParentalConsentForms = RequiresConsent.Count((V)=>V) };
        }

        const int NumberOnFirstPage = 2;
        const int NumberPerPage = 3;

        const string FirstPageQuery =
            "SELECT        M.FirstName, M.Surname, M.HomePhone, M.Email1, Ms.BCUCardReqd, Ms.BCUNumber, Ms.BCURenewalDate, Ms.MembershipTypeRC, Mt.FullYearRate, Ms.SignatureReqd, Ms.BCUCardReqd, Ms.ConcessionProofReqd, " +
            "                         Ms.ParentalConsentReqd, M.Address1, M.Address2, M.Address3, M.Town, M.County, M.PostCode, Y.BCUNonMemberRate, Y.RackRate, Ms.ID " +
            "FROM            SSCC_DAT_Family AS F INNER JOIN" +
            "                         SSCC_DAT_Member AS M ON F.Member = M.ID INNER JOIN" +
            "                         SSCC_DAT_Membership AS Ms ON M.ID = Ms.Member INNER JOIN" +
            "                         SSCC_DAT_Year AS Y ON Ms.Year = Y.ID INNER JOIN" +
            "                         SSCC_DAT_MembershipType AS Mt ON Ms.Year = Mt.Year AND Ms.MembershipTypeRC = Mt.MembershipTypeRC " +
            "WHERE        (F.UserID = @Username) AND (Y.StartDate < @NOW) AND (Y.EndDate > @NOW) AND Ms.RenewChecked=1";
        [OperationContract]
        public FirstPage LoadFirstPage()
        {
            // Add your operation implementation here
            var FP = new FirstPage();
            string UserName = HttpContext.Current.User.Identity.Name;
            using (var Q = SSCCDatabase.Query(FirstPageQuery, new Params()
            {
                {new SqlParameter("@Username", SqlDbType.VarChar), UserName},
                {new SqlParameter("@NOW", SqlDbType.Date), DateTime.Now}
            }))
            {
                FP.Members = Q.Select((R) =>
                    {
                        var MD = new MemberData()
                        {
                            FullName = String.Format("{0} {1}", R["FirstName"], R["Surname"]),
                            Address = "",
                            HomeTelephone = R["HomePhone"].ToString(),
                            Email = R["Email1"].ToString(),
                            MembershipType = R["MembershipTypeRC"].Nullable<int?>().GetRefCodeShortName(),
                            BCU = null,
                            Racks = null,
                            Total = 0
                        };
                        MD.Rate = (decimal)R["FullYearRate"];
                        MD.rqSignedRenewalForm = (bool)R["SignatureReqd"];
                        MD.rqBCUCard = R["BCUCardReqd"].Nullable<bool?>().HasValue? R["BCUCardReqd"].Nullable<bool?>().Value : false ;
                        MD.rqConcessionProof = (R["ConcessionProofReqd"].Nullable<bool?>().HasValue) ? R["ConcessionProofReqd"].Nullable<bool?>().Value : false;
                        MD.ParentalConsent = (R["ParentalConsentReqd"].Nullable<bool?>().HasValue) ? R["ParentalConsentReqd"].Nullable<bool?>().Value : false;

                        MD.Address = R["Address1"].ToString();
                        if (R["Address2"].ToString() != "")
                        {
                            MD.Address += ", " + R["Address2"].ToString();
                        }
                        if (R["Address3"].ToString() != "")
                        {
                            MD.Address += ", " + R["Address3"].ToString();
                        }
                        if (R["Town"].ToString() != "")
                        {
                            MD.Address += ", " + R["Town"].ToString();
                        }
                        if (R["County"].ToString() != "")
                        {
                            MD.Address += ", " + R["County"].ToString();
                        }
                        if (R["PostCode"].ToString() != "")
                        {
                            MD.Address += ", " + R["PostCode"].ToString();
                        }


                        //if (R["MembershipTypeRC"].Nullable<int?>().GetRefCodeMetadata<bool>() && (R["BCUNumber"].ToString() == "") && (!R["BCURenewalDate"].Nullable<DateTime?>().HasValue || R["BCURenewalDate"].Nullable<DateTime?>().Value < DateTime.Now))
                        //{
                        //    MD.BCU = R["BCUNonMemberRate"].Nullable<decimal?>();
                        //}


                        if (R["MembershipTypeRC"].Nullable<int?>().GetRefCodeMetadata<bool>() && !(R["BCUCardReqd"].Nullable<bool?>()==true))
                        {
                            MD.BCU = R["BCUNonMemberRate"].Nullable<decimal?>();
                        }

                        using (var Racks = SSCCDatabase.Query("SELECT COUNT(*) AS NumberOfRacks FROM SSCC_DAT_RackAllocation WHERE (Membership = @MembershipID) AND (Renew = 1) GROUP BY Membership",
                            new SqlParameter("@MembershipID", SqlDbType.Int), R["ID"]))
                        {
                            try
                            {
                                int? NumberOfRacks = Racks.FirstOrDefault()["NumberOfRacks"].Nullable<int?>();
                                MD.Racks = (!NumberOfRacks.HasValue || NumberOfRacks == 0) ? null : (decimal?)NumberOfRacks * (decimal)R["RackRate"];
                            }
                            catch (Exception)
                            {
                            }

                        }
                        MD.Total = MD.Rate;
                        if (MD.Racks.HasValue)
                            MD.Total += MD.Racks.Value;
                        if (MD.BCU.HasValue)
                            MD.Total += MD.BCU.Value;
                        return MD;
                    }).ToArray();
            }

            FP.MembersConsent = MemberConsents(UserName, 0, NumberOnFirstPage);
            FP.TotalMoney = FP.Members.Select((FPi) => FPi.Total).Sum();
            return FP;
        }

        [OperationContract]
        public AdditionalPage LoadAdditionalPage(int PageNo)
        {
            string UserName = HttpContext.Current.User.Identity.Name;
            var AP = new AdditionalPage();
            ErrorHandlerBehavior.Log(String.Format("Loading Page Number {0}.  Starting with {1} and taking {2}", PageNo, NumberOnFirstPage + NumberPerPage * PageNo, NumberPerPage));
            AP.MembersConsent = MemberConsents(UserName, NumberOnFirstPage + NumberPerPage * PageNo, NumberPerPage);
            return AP;
        }
        [OperationContract]
        public ParentalConsentForm LoadParentalConsent(int PageNo)
        {
            string UserName = HttpContext.Current.User.Identity.Name;
            var PCF = new ParentalConsentForm();

            string QString =
                "SELECT        M.FirstName, M.Surname, M.TownOptOut, M.HomePhoneOptOut, M.WorkPhoneOptOut, M.MobilePhoneOptOut, M.Email1OptOut, M.Email2OptOut, M.ImageOptOut, " +
                "                         M.EMPhoneOptOut, M.EMMobileOptOut, " +
                "               M.DrName, M.DrPhone, M.Medical, M.CanSwim " +
                "FROM            SSCC_DAT_Family AS F INNER JOIN " +
                "                         SSCC_DAT_Member AS M ON F.Member = M.ID INNER JOIN " +
                "                         SSCC_DAT_Membership AS Ms ON M.ID = Ms.Member INNER JOIN " +
                "                         SSCC_DAT_Year AS Y ON Ms.Year = Y.ID " +
                "WHERE        (F.UserID = @Username) AND (Ms.RenewChecked = 1) AND (Y.StartDate < @NOW) AND (Y.EndDate > @NOW) AND (Ms.ParentalConsentReqd = 1) ";

            var Parameters = new Params()
            {
                {new SqlParameter("@Username", SqlDbType.VarChar), UserName},
                {new SqlParameter("@NOW", SqlDbType.Date), DateTime.Now}
            };
            using (var Q = SSCCDatabase.Query(QString, Parameters))
            {
                var I = Q.TakeRange(PageNo, 1).First();
                PCF.Name = String.Format("{0} {1}", I["FirstName"], I["Surname"]);
                PCF.CanSwim = (bool)I["CanSwim"];
                PCF.DoctorName = I["DrName"].ToString();
                PCF.DoctorPhone = I["DrPhone"].ToString();
                PCF.Medical = I["Medical"].ToString();
                PCF.ImageConsent = !(bool)I["ImageOptOut"];
                PCF.contactConsent = "";
                if (I["TownOptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "town";
                    else
                        PCF.contactConsent += ", town";
                }
                if (I["HomePhoneOptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "home phone";
                    else
                        PCF.contactConsent += ", home phone";
                }
                if (I["WorkPhoneOptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "work phone";
                    else
                        PCF.contactConsent += ", work phone";
                }
                if (I["MobilePhoneOptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "mobile phone";
                    else
                        PCF.contactConsent += ", mobile phone";
                }
                if (I["Email1OptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "email";
                    else
                        PCF.contactConsent += ", email";
                }
                if (I["Email2OptOut"].Nullable<bool?>() != true)
                {
                    if (PCF.contactConsent == "")
                        PCF.contactConsent += "secondary email";
                    else
                        PCF.contactConsent += ", secondary email";
                }
                if (PCF.contactConsent.Contains(","))
                {
                    PCF.contactConsent = PCF.contactConsent.Substring(0, PCF.contactConsent.LastIndexOf(",")) + " and" + PCF.contactConsent.Substring(PCF.contactConsent.LastIndexOf(",") + 1);
                }
                PCF.EmergencyConsent = !((bool)I["EMPhoneOptOut"] && (bool)I["EMMobileOptOut"]);
            }
            return PCF;
        }


        private MemberConsent[] MemberConsents(string Username, int StartIndex, int count)
        {
            string QString =
                "SELECT        M.FirstName, M.Surname, M.TownOptOut, M.HomePhoneOptOut, M.WorkPhoneOptOut, M.MobilePhoneOptOut, M.Email1OptOut, M.Email2OptOut, M.ImageOptOut, " +
                "                         M.EMPhoneOptOut, M.EMMobileOptOut, Ms.Age " +
                "FROM            SSCC_DAT_Family AS F INNER JOIN "+
                "                         SSCC_DAT_Member AS M ON F.Member = M.ID INNER JOIN "+
                "                         SSCC_DAT_Membership AS Ms ON M.ID = Ms.Member INNER JOIN "+
                "                         SSCC_DAT_Year AS Y ON Ms.Year = Y.ID "+
                "WHERE        (F.UserID = @Username) AND (Ms.RenewChecked = 1) AND (Y.StartDate < @NOW) AND (Y.EndDate > @NOW)";
            using (var Q = SSCCDatabase.Query(QString, new Params()
            {
                {new SqlParameter("@Username", SqlDbType.VarChar), Username},
                {new SqlParameter("@NOW", SqlDbType.Date), DateTime.Now}
            }))
            {
                return Q.Select((R) =>
                    {
                        var MC = new MemberConsent();
                        MC.MemberName = String.Format("{0} {1}", R["FirstName"], R["Surname"]);
                        MC.ImageConsent = !(bool)R["ImageOptOut"];
                        MC.contactConsent = "";
                        if (R["TownOptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "town";
                            else
                                MC.contactConsent += ", town";
                        }
                        if (R["HomePhoneOptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "home phone";
                            else
                                MC.contactConsent += ", home phone";
                        }
                        if (R["WorkPhoneOptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "work phone";
                            else
                                MC.contactConsent += ", work phone";
                        }
                        if (R["MobilePhoneOptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "mobile phone";
                            else
                                MC.contactConsent += ", mobile phone";
                        }
                        if (R["Email1OptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "email";
                            else
                                MC.contactConsent += ", email";
                        }
                        if (R["Email2OptOut"].Nullable<bool?>() != true)
                        {
                            if (MC.contactConsent == "")
                                MC.contactConsent += "secondary email";
                            else
                                MC.contactConsent += ", secondary email";
                        }
                        if (MC.contactConsent.Contains(","))
                        {
                            MC.contactConsent = MC.contactConsent.Substring(0, MC.contactConsent.LastIndexOf(",")) + " and" + MC.contactConsent.Substring(MC.contactConsent.LastIndexOf(",") + 1);
                        }
                        MC.EmergencyConsent = !((bool)R["EMPhoneOptOut"] && (bool)R["EMMobileOptOut"]);
                        int? age = R["Age"].Nullable<int?>();
                        MC.Under18 = (age.HasValue && age.Value < 18);
                        return MC;
                    }
                    ).TakeRange(StartIndex, count).ToArray();
            }
        }
        // Add more operations here and mark them with [OperationContract]

        public class HowManyPages
        {
            public int NumberOfAdditionalPages { get; set; }
            public int NumberOfParentalConsentForms { get; set; }
        }
        public class FirstPage
        {
            public MemberData[] Members { get; set; }
            public decimal TotalMoney { get; set; }
            public MemberConsent[] MembersConsent { get; set; }
        }
        public class AdditionalPage
        {
            public MemberConsent[] MembersConsent { get; set; }
        }
        public class ParentalConsentForm
        {
            public string Name { get; set; }
            public bool CanSwim { get; set; }
            public string DoctorName { get; set; }
            public string DoctorPhone { get; set; }
            public string Medical { get; set; }
            public bool ImageConsent { get; set; }
            public string contactConsent { get; set; }
            public bool EmergencyConsent { get; set; }
        }

        public class MemberData
        {

            public string FullName { get; set; }

            //Contact
            public string Address { get; set; }
            public string HomeTelephone { get; set; }
            public string Email { get; set; }

            //Membership
            public string MembershipType { get; set; }
            public decimal Rate { get; set; }
            public decimal? BCU { get; set; }
            public decimal? Racks { get; set; }
            public decimal Total { get; set; }

            //RequiredDocuments
            public bool rqSignedRenewalForm { get; set; }
            public bool? rqBCUCard { get; set; }
            public bool rqConcessionProof { get; set; }
            public bool ParentalConsent { get; set; }
        }
        public class MemberConsent
        {
            public string contactConsent { get; set; }
            public string MemberName { get; set; }
            public bool EmergencyConsent { get; set; }
            public bool ImageConsent { get; set; }
            public bool Under18 { get; set; }
        }
    }
    public static class RangeExtension
    {
        public static IEnumerable<T> TakeRange<T>(this IEnumerable<T> v, int StartIndex, int count)
        {
            //v = v.ToArray();
            //int Count1 = v.SkipWhile((va, i) => i < StartIndex).TakeWhile((va, i) => i < count).Count();
            //int Count2 = v.SkipWhile((va, i) => i < StartIndex).TakeWhile((va, i) => i < count+StartIndex).Count();
            //ErrorHandlerBehavior.Log(String.Format("We counted {0} for start {1} and Finish {2}", Count1, StartIndex, count));
            //ErrorHandlerBehavior.Log(String.Format("We counted {0} for start {1} and Finish {2}", Count2, StartIndex, count + StartIndex));
            return v.SkipWhile((va, i) => i < StartIndex).TakeWhile((va, i) => i < count);
        }
    }
}
